'use strict';

const Controller = require('egg').Controller;

class BlogsController extends Controller {
  async index() {
    const { app, response: res, request: req, logger } = this.ctx;
    // console.log('blog/index', req);
    let {
      pageNo = 1,
      pageSize = 20,
      keywords = '',
      order = 'desc',
      by = 'created_at',
      // eslint-disable-next-line no-unused-vars
      limit = '10',
      // eslint-disable-next-line no-unused-vars
      offset = '0',
    } = req.query;
    const { Sequelize } = app;
    pageNo = isNaN(parseInt(pageNo, 10)) ? 1 : parseInt(pageNo, 10);
    pageSize = isNaN(parseInt(pageSize, 10)) ? 10 : parseInt(pageSize, 10);
    offset = isNaN(parseInt(offset, 10)) ? 1 : parseInt(offset, 10);
    limit = isNaN(parseInt(limit, 10)) ? 10 : parseInt(limit, 10);
    if (!/^(asc|desc)$/.test(order)) {
      logger.info('order值无效');
      res.body = {
        code: 401,
      };
      return;
    }
    // 判断排序字段是否有效
    if (by !== 'created_at') {
      const columns = await app.model.Blog.describe();
      if (by in columns) {
        by = 'created_at';
      }
    }
    const listCondation = {
      attributes: ['id', 'hash', 'name', 'status', 'created_at', 'updated_at'],
      order: [
        ['status', 'asc'],
        ['created_at', 'desc'],
      ],
      where: {},
      limit: pageSize,
      offset: (pageNo - 1) * pageSize,
    };

    const countCondation = {
      where: {},
    };
    console.log('req.headers.platform', req.headers.platform);
    if (req.headers.platform.toLowerCase() === 'client') {
      listCondation.where.status = 1;
      countCondation.where.status = 1;
    }
    if (keywords) {
      listCondation.where.name = { [Sequelize.Op.like]: `%${keywords}%` };
      countCondation.where.name = {
        [Sequelize.Op.like]: `%${keywords}%`,
      };
    }
    let blogs = [],
      blog_count = 0;
    blogs = await app.model.Blog.findAll(listCondation);

    blog_count = await app.model.Blog.count(countCondation);

    res.body = {
      list: blogs,
      total: blog_count,
    };
  }
  async show() {
    const { response: res, app, params, logger } = this.ctx;
    const hash = params.id;
    const blog = await app.model.Blog.findByHash(hash);
    if (!blog) {
      res.body = {
        code: 401,
      };
      return false;
    }
    // 查询相邻的两篇文章
    logger.info('blog.id', blog.id);
    const prevBlog = await app.model.Blog.findPrev(blog.id);
    const nextBlog = await app.model.Blog.findNext(blog.id);

    blog.increment('view_count');
    res.body = {
      blog,
      prev: prevBlog,
      next: nextBlog,
    };
  }
  async create() {
    const { app, request: req, response: res, helper, logger } = this.ctx;
    let { title, content, hash, labels = [] } = req.body;
    title && (title = title.trim());
    content && (content = content.trim());
    hash && (hash = hash.trim());

    if (!title) {
      res.body = {
        msg: '标题不能为空',
      };
      return;
    }
    if (title.length > 100) {
      res.body = {
        msg: '标题不能超过100个字符',
      };
      return;
    }
    if (!content) {
      res.body = {
        msg: '内容不能为空',
      };
      return;
    }
    if (!Array.isArray(labels)) {
      res.body = {
        code: 401,
      };
      return;
    }

    // 判断标签值是否有效
    // if (labels.length > 0) {
    //   const label = await app.model.Label.findByName(labels);
    //   if (label) {
    //     if (!blog) {
    //       res.body = {
    //         msg: '存在非法标签，请稍后重新配置标签',
    //       };
    //       return false;
    //     }
    //   }
    // }
    const blogHash = hash || helper.hash(32);
    const tr = await app.model.transaction();
    try {
      const blog = await app.model.Blog.create(
        {
          name: title,
          content,
          user_id: app.userInfo.id,
          hash: blogHash,
          status: 0,
          created_at: helper.now(),
          updated_at: helper.now(),
        },
        {
          transaction: tr,
        }
      );

      if (labels.length > 0) {
        // 插入新的标签记录
        await app.model.BlogMapLabel.bulkCreate(
          [
            ...labels
              .filter(item => !!item)
              .map(item => {
                return {
                  label_id: item,
                  blog_id: blog.id,
                  created_at: helper.now(),
                  updated_at: helper.now(),
                };
              }),
          ],
          {
            transaction: tr,
          }
        );
      }
      // 写入文件
      const path = require('path');
      const baseDir = path.resolve(app.baseDir, './uploads');
      const docsDir = path.resolve(baseDir, './blogs');
      const blogDir = path.resolve(docsDir, `./${blogHash}`);
      const fs = require('fs');
      if (!fs.existsSync(blogDir)) {
        fs.mkdirSync(blogDir);
        fs.mkdirSync(path.resolve(blogDir, './images'));
      }
      fs.writeFileSync(path.resolve(blogDir, './readme.md'), content);
      tr.commit();
      res.body = blog;
    } catch (e) {
      logger.err(new Error(e));
      tr.rollback();
      res.body = {
        code: 500,
      };
    }
  }

  async update() {
    // 根据ID修改文章内容
    const { app, request: req, response: res, helper, logger } = this.ctx;
    let { title, content, id, status } = req.body;
    title && (title = title.trim());
    content && (content = content.trim());
    id && (id = String(id).trim());

    if (!id) {
      res.body = {
        code: 401,
      };
      return false;
    }

    if (!title) {
      res.body = {
        msg: '标题不能为空',
      };
      return false;
    }
    // 判断status是否是非法值
    if (status && !/^[0-2]$/g.test(status)) {
      res.body = {
        code: 401,
      };
      return false;
    }
    if (!content) {
      res.body = {
        msg: '内容不能为空',
      };
      return false;
    }
    logger.info('参数校验通过');
    const blog = await app.model.Blog.exists(id);

    if (!blog) {
      res.body = {
        code: 401,
      };
      return false;
    }

    // 更新文章内容
    const tr = await app.model.transaction();
    try {
      const row = {
        name: title,
        content,
        status: status || 0,
        updated_at: helper.now(),
      };
      this.ctx.logger.info('blog row:', row);
      await blog.update(row, {
        transaction: tr,
      });

      // 写入文件
      const path = require('path');
      const baseDir = path.resolve(app.baseDir, './uploads');
      const docsDir = path.resolve(baseDir, './blogs');
      const blogDir = path.resolve(docsDir, `./${blog.hash}`);
      const fs = require('fs');
      if (!fs.existsSync(blogDir)) {
        fs.mkdirSync(blogDir);
        fs.mkdirSync(path.resolve(blogDir, './images'));
      }
      fs.writeFileSync(path.resolve(blogDir, './readme.md'), content);
      tr.commit();
      res.body = blog;
    } catch (e) {
      logger.error(new Error(e));
      tr.rollback();
      res.body = {
        code: 500,
      };
    }
  }
  async toggleStatus() {
    const { app, request: req, response: res } = this.ctx;
    const { id, status } = req.body;

    if (status !== 0 && status !== 1) {
      res.body = {
        code: 401,
      };
      return;
    }

    const blog = await app.model.Blog.findById(id);

    if (!blog) {
      res.body = {
        code: 401,
      };
      return;
    }
    await blog.update({
      status,
    });
  }
  async destroy() {
    const { response: res, app, params, logger } = this.ctx;
    const id = params.id.trim();
    if (!id) {
      this.logger.log('id为空', id);
      res.body = {
        code: 401,
      };
      return;
    }
    // 判断ID是否有效
    const blog = await app.model.Blog.findOne({
      where: {
        id,
      },
    });
    if (!blog) {
      logger.error('文章id无效', id);
      res.body = {
        code: 401,
      };
      return;
    }
    await blog.update({
      status: 2,
    });
  }
}
module.exports = BlogsController;
